{
    "cells": [
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "# AI 高手之路 10：机器学习概览——AI 学习的“路线图” - 代码示例\n",
       "\n",
       "本 Jupyter Notebook 包含了博客文章 \"AI 高手之路 10：机器学习概览——AI 学习的“路线图”\" 中所有的代码示例。\n",
       "\n",
       "你可以逐个运行这些代码，加深对机器学习概念和流程的理解。\n",
       "\n",
       "---\n"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 1. 监督学习示例（分类任务 - 鸢尾花数据集）\n",
       "\n",
       "以下代码演示了如何使用 scikit-learn 库进行监督学习的分类任务。我们使用经典的鸢尾花数据集，并使用随机森林分类器进行训练和预测。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "from sklearn.model_selection import train_test_split\n",
       "from sklearn.ensemble import RandomForestClassifier\n",
       "from sklearn.metrics import accuracy_score\n",
       "from sklearn.datasets import load_iris\n",
       "\n",
       "# 加载数据集\n",
       "data = load_iris()\n",
       "X = data['data']  # 输入特征 (花萼长度, 花萼宽度, 花瓣长度, 花瓣宽度)\n",
       "y = data['target']  # 目标标签 (鸢尾花的种类: 0, 1, 2)\n",
       "\n",
       "# 数据集划分为训练集和测试集\n",
       "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
       "\n",
       "# 初始化随机森林分类器 (一种常用的监督学习模型)\n",
       "model = RandomForestClassifier(n_estimators=100, random_state=42)\n",
       "# 使用训练数据训练模型\n",
       "model.fit(X_train, y_train)\n",
       "\n",
       "# 使用测试数据进行预测\n",
       "predictions = model.predict(X_test)\n",
       "# 评估模型准确率\n",
       "accuracy = accuracy_score(y_test, predictions)\n",
       "print(f\"模型准确率: {accuracy:.2f}\")"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "这段代码使用了 `scikit-learn` 库，这是一个非常流行的Python机器学习库。\n",
       "\n",
       "1.  **加载数据集**: `load_iris()` 函数加载了经典的鸢尾花数据集，包含了鸢尾花的各种特征和对应的种类标签。\n",
       "2.  **划分数据集**: `train_test_split()` 函数将数据集划分为训练集和测试集，训练集用于训练模型，测试集用于评估模型性能。\n",
       "3.  **初始化模型**: `RandomForestClassifier()` 创建了一个随机森林分类器模型。随机森林是一种集成学习方法，通过组合多个决策树来提高预测准确性和鲁棒性。\n",
       "4.  **模型训练**: `model.fit(X_train, y_train)` 使用训练集数据训练模型，模型会学习特征和标签之间的关系。\n",
       "5.  **模型预测**: `model.predict(X_test)` 使用训练好的模型对测试集数据进行预测，得到预测的类别标签。\n",
       "6.  **模型评估**: `accuracy_score(y_test, predictions)` 计算模型在测试集上的准确率，评估模型的性能。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 2. 无监督学习示例（聚类任务 - KMeans）\n",
       "\n",
       "以下代码演示了如何使用 KMeans 算法进行聚类。我们生成一些示例数据，并使用 KMeans 算法将数据聚类成 4 个簇，并可视化聚类结果。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "from sklearn.cluster import KMeans\n",
       "from sklearn.datasets import make_blobs\n",
       "import matplotlib.pyplot as plt\n",
       "\n",
       "# 生成示例数据，模拟未标注的数据\n",
       "X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=42)\n",
       "\n",
       "# 初始化KMeans聚类器，设定聚类中心数量为4\n",
       "kmeans = KMeans(n_clusters=4, random_state=42, n_init=10) # n_init to suppress warning\n",
       "# 使用数据进行聚类，并得到每个数据点的聚类标签\n",
       "y_kmeans = kmeans.fit_predict(X)\n",
       "\n",
       "# 可视化聚类结果\n",
       "plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, cmap='viridis', label='Data Points') # 绘制数据点，颜色表示不同的簇\n",
       "plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red', label='Centroids') # 绘制聚类中心\n",
       "plt.title('K-Means Clustering')\n",
       "plt.xlabel('Feature 1')\n",
       "plt.ylabel('Feature 2')\n",
       "plt.legend()\n",
       "plt.show()"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "1.  **生成示例数据**: `make_blobs()` 函数生成了一些随机数据点，这些数据点天然地分为4个簇，用于模拟实际应用中未标注的数据。\n",
       "2.  **初始化 KMeans 聚类器**: `KMeans(n_clusters=4, random_state=42)` 创建了一个 KMeans 聚类器，指定要将数据聚类成 4 个簇。`n_init=10`是为了避免警告信息，在实际使用中建议设置。\n",
       "3.  **数据聚类**: `kmeans.fit_predict(X)` 使用 KMeans 算法对数据进行聚类。`fit_predict()` 函数先训练模型（找到簇中心），然后预测每个数据点所属的簇，并返回每个数据点的簇标签。\n",
       "4.  **可视化聚类结果**: 使用 `matplotlib.pyplot` 库将聚类结果可视化，展示数据点的分布和聚类中心的位置。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 3. 强化学习环境交互示例 (CartPole)\n",
       "\n",
       "以下代码演示了如何使用 `gym` 库创建一个 CartPole 环境，并进行随机动作与环境交互。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "import gym\n",
       "\n",
       "# 创建 CartPole 环境 (一个经典的强化学习环境，目标是保持杆子竖直)\n",
       "env = gym.make(\"CartPole-v1\")\n",
       "# 重置环境，获取初始状态\n",
       "state = env.reset()\n",
       "\n",
       "for step in range(200): # 运行 200 步\n",
       "    # 从动作空间中随机选择一个动作 (CartPole 环境的动作空间是离散的，只有两个动作：向左推车或向右推车)\n",
       "    action = env.action_space.sample()\n",
       "    # 执行动作，与环境交互，获取下一个状态、奖励、是否结束、信息\n",
       "    next_state, reward, terminated, truncated, info = env.step(action)\n",
       "    # 渲染环境，可视化当前状态 (需要安装图形界面支持)\n",
       "    env.render()\n",
       "    if terminated or truncated: # 如果游戏结束 (杆子倒下或达到最大步数)\n",
       "        break\n",
       "\n",
       "env.close() # 关闭环境"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "这段代码使用了 `gym` 库，这是一个流行的强化学习环境库，提供了各种各样的环境用于开发和测试强化学习算法。\n",
       "\n",
       "1.  **创建环境**: `gym.make(\"CartPole-v1\")` 创建了一个 CartPole 环境。在这个环境中，一个杆子通过一个关节连接到一个可以在水平轨道上移动的小车上。智能体的目标是通过控制小车的左右移动来保持杆子竖直。\n",
       "2.  **重置环境**: `env.reset()` 重置环境到初始状态，并返回初始状态。\n",
       "3.  **循环交互**: `for step in range(200):` 循环运行 200 步，模拟智能体与环境的交互过程。\n",
       "4.  **随机选择动作**: `env.action_space.sample()` 从环境的动作空间中随机选择一个动作。在 CartPole 环境中，动作空间是离散的，包含两个动作：0 (向左推车) 和 1 (向右推车)。\n",
       "5.  **执行动作**: `env.step(action)` 执行选择的动作，环境会返回执行动作后的下一个状态 (`next_state`)、获得的奖励 (`reward`)、游戏是否结束 (`terminated` 和 `truncated`) 以及一些额外的信息 (`info`)。\n",
       "6.  **渲染环境**: `env.render()` 可视化当前环境的状态，需要安装图形界面支持才能看到可视化效果。\n",
       "7.  **判断游戏结束**: `if terminated or truncated:` 判断游戏是否结束，如果结束则跳出循环。`terminated` 表示环境自然结束（例如，在 CartPole 环境中，杆子倒下），`truncated` 表示由于达到时间限制或其他外部原因而人为终止。\n",
       "8.  **关闭环境**: `env.close()` 关闭环境，释放资源。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 4. 数据清洗示例\n",
       "\n",
       "以下代码演示了如何使用 Pandas 库进行数据导入和清洗，包括处理缺失值和重复值。示例数据 `data.csv` 包含一些缺失值和重复行。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "import pandas as pd\n",
       "import numpy as np\n",
       "\n",
       "# 导入数据，假设数据文件为 \"data.csv\"\n",
       "data = pd.read_csv(\"data.csv\")\n",
       "\n",
       "# 查看数据基本信息，如列名、数据类型、缺失值等\n",
       "print(\"原始数据信息:\\n\")\n",
       "print(data.info())\n",
       "\n",
       "# 处理缺失值：使用均值填充数值型缺失值\n",
       "data.fillna(data.mean(numeric_only=True), inplace=True) # numeric_only to avoid warning\n",
       "\n",
       "# 处理缺失值：使用众数填充类别型缺失值 (如果存在类别型特征)\n",
       "for column in data.select_dtypes(include='object').columns: # 'object' dtype for string columns\n",
       "    data[column].fillna(data[column].mode()[0], inplace=True)\n",
       "\n",
       "# 处理重复值：删除重复行\n",
       "data.drop_duplicates(inplace=True)\n",
       "\n",
       "# 打印清洗后的数据信息\n",
       "print(\"\\n数据清洗后的信息:\\n\")\n",
       "print(data.info())\n",
       "\n",
       "print(\"\\n清洗后的数据前几行:\\n\")\n",
       "print(data.head())"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "1.  **导入数据**: `pd.read_csv(\"data.csv\")` 使用 Pandas 库读取 CSV 文件数据到 DataFrame 中。\n",
       "2.  **查看数据信息**: `data.info()` 打印 DataFrame 的摘要信息，包括列名、非空值数量、数据类型等，用于初步了解数据质量和缺失情况。\n",
       "3.  **填充缺失值 (数值型)**: `data.fillna(data.mean(numeric_only=True), inplace=True)` 使用每列的均值填充数值型特征的缺失值。`numeric_only=True` 参数用于仅计算数值列的均值，避免警告。`inplace=True` 表示直接在原 DataFrame 上修改。\n",
       "4.  **填充缺失值 (类别型)**:  代码注释部分展示了如何使用众数填充类别型特征的缺失值。`data.select_dtypes(include='object').columns` 选择所有数据类型为 'object' 的列（通常是字符串类型的类别特征）。`data[column].mode()[0]` 计算每列的众数（出现次数最多的值），并使用众数填充缺失值。\n",
       "5.  **删除重复值**: `data.drop_duplicates(inplace=True)` 删除 DataFrame 中的重复行。\n",
       "6.  **打印清洗后的数据信息**: 再次打印 `data.info()` 和 `data.head()`，查看数据清洗后的信息和前几行数据，确认清洗效果。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 5. 数据预处理示例 (特征标准化)\n",
       "\n",
       "以下代码演示了如何使用 StandardScaler 进行特征标准化，将特征缩放到均值为 0，方差为 1 的范围。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "from sklearn.preprocessing import StandardScaler\n",
       "import numpy as np\n",
       "\n",
       "# 假设 X 是特征数据，已经加载或清洗过\n",
       "# 示例数据 (假设 X 是一个 numpy 数组)\n",
       "X = np.array([[1, 10], [2, 20], [3, 30], [4, 40], [5, 50]])\n",
       "\n",
       "# 初始化 StandardScaler\n",
       "scaler = StandardScaler()\n",
       "# 使用 scaler 对数据进行标准化 (fit_transform 同时完成拟合和转换)\n",
       "X_scaled = scaler.fit_transform(X)\n",
       "\n",
       "print(\"原始数据 X:\\n\", X)\n",
       "print(\"\\n标准化后的数据 X_scaled:\\n\", X_scaled)"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "1.  **导入 StandardScaler**: `from sklearn.preprocessing import StandardScaler` 导入 StandardScaler 类，用于特征标准化。\n",
       "2.  **示例数据**:  `X = np.array(...)` 创建一个示例特征数据 `X`，假设它包含了数值型特征。\n",
       "3.  **初始化 StandardScaler**: `scaler = StandardScaler()` 创建一个 StandardScaler 对象。\n",
       "4.  **数据标准化**: `X_scaled = scaler.fit_transform(X)` 使用 `fit_transform()` 方法对数据 `X` 进行标准化。\n",
       "    *   `fit()` 方法计算训练数据的均值和标准差。\n",
       "    *   `transform()` 方法使用 `fit()` 中计算的均值和标准差对数据进行标准化，公式为： `(x - mean) / std`.\n",
       "    *   `fit_transform()` 方法是 `fit()` 和 `transform()` 的组合，通常在训练数据上使用，一步完成拟合和转换。\n",
       "5.  **打印结果**: 打印原始数据 `X` 和标准化后的数据 `X_scaled`，对比标准化效果。标准化后的数据均值接近 0，标准差接近 1。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 6. 特征工程示例 (特征选择 - 方差选择法)\n",
       "\n",
       "以下代码演示了如何使用 VarianceThreshold 进行特征选择，移除方差低于设定阈值的特征。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "from sklearn.feature_selection import VarianceThreshold\n",
       "import numpy as np\n",
       "\n",
       "# 假设 X 是特征数据\n",
       "# 示例数据 (假设 X 是一个 numpy 数组)\n",
       "X = np.array([[0, 0, 1], [0, 1, 0], [0, 2, 1], [1, 0, 2], [0, 1, 1], [0, 2, 0]])\n",
       "\n",
       "print(\"原始数据 X:\\n\", X)\n",
       "\n",
       "# 初始化 VarianceThreshold，设定方差阈值为 0.1\n",
       "selector = VarianceThreshold(threshold=0.1)\n",
       "# 使用 selector 对数据进行特征选择 (fit_transform 同时完成拟合和转换)\n",
       "X_selected = selector.fit_transform(X)\n",
       "\n",
       "print(\"\\n特征选择后的数据 X_selected:\\n\", X_selected)\n",
       "print(\"\\n被选择的特征索引:\", selector.get_support(indices=True)) # 获取被选择的特征索引"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "1.  **导入 VarianceThreshold**: `from sklearn.feature_selection import VarianceThreshold` 导入 VarianceThreshold 类，用于方差选择法特征选择。\n",
       "2.  **示例数据**: `X = np.array(...)` 创建一个示例特征数据 `X`。\n",
       "3.  **初始化 VarianceThreshold**: `selector = VarianceThreshold(threshold=0.1)` 创建一个 VarianceThreshold 对象，并设置方差阈值 `threshold=0.1`。方差低于 0.1 的特征将被移除。\n",
       "4.  **特征选择**: `X_selected = selector.fit_transform(X)` 使用 `fit_transform()` 方法对数据 `X` 进行特征选择。\n",
       "    *   `fit()` 方法计算每个特征的方差。\n",
       "    *   `transform()` 方法移除方差低于阈值的特征。\n",
       "    *   `fit_transform()` 方法是 `fit()` 和 `transform()` 的组合。\n",
       "5.  **打印结果**: \n",
       "    *   打印原始数据 `X` 和特征选择后的数据 `X_selected`，对比特征选择效果。可以看到，方差较小的第一列特征（值都为 0 或接近 0）被移除。\n",
       "    *   `selector.get_support(indices=True)` 获取被选择的特征的索引，返回一个数组，表示被保留的特征在原始特征中的索引位置。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 7. 数据集划分示例\n",
       "\n",
       "以下代码演示了如何使用 `train_test_split` 函数将数据集划分为训练集、验证集和测试集。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "from sklearn.model_selection import train_test_split\n",
       "from sklearn.datasets import load_iris\n",
       "\n",
       "# 加载示例数据集 (鸢尾花数据集)\n",
       "iris = load_iris()\n",
       "X, y = iris.data, iris.target\n",
       "\n",
       "# 划分数据集，test_size=0.2 表示测试集占总数据的 20%，random_state 设置随机种子保证可重复性\n",
       "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
       "\n",
       "# 再次划分训练集，得到训练集和验证集，validation_size=0.25 表示验证集占训练集的 25%\n",
       "X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=42) # 0.25 x 0.8 = 0.2 of total data\n",
       "\n",
       "print(\"训练集特征 X_train shape:\", X_train.shape)\n",
       "print(\"训练集标签 y_train shape:\", y_train.shape)\n",
       "print(\"验证集特征 X_val shape:\", X_val.shape)\n",
       "print(\"验证集标签 y_val shape:\", y_val.shape)\n",
       "print(\"测试集特征 X_test shape:\", X_test.shape)\n",
       "print(\"测试集标签 y_test shape:\", y_test.shape)"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "1.  **导入 `train_test_split`**: `from sklearn.model_selection import train_test_split` 导入 `train_test_split` 函数，用于划分数据集。\n",
       "2.  **加载数据集**: `iris = load_iris(); X, y = iris.data, iris.target` 加载鸢尾花数据集作为示例数据。\n",
       "3.  **划分训练集和测试集**: `X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)` 使用 `train_test_split` 函数将数据集划分为训练集和测试集。\n",
       "    *   `test_size=0.2` 设置测试集大小为总数据的 20%。\n",
       "    *   `random_state=42` 设置随机种子，保证每次运行代码划分结果一致，方便复现。\n",
       "4.  **划分训练集和验证集**: `X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=42)` 再次使用 `train_test_split` 函数，在训练集的基础上划分出验证集。`test_size=0.25` 表示验证集大小为 **训练集** 的 25%，即占总数据的 20% (0.25 * 0.8 = 0.2)。\n",
       "5.  **打印数据集形状**: 打印训练集、验证集、测试集的特征和标签的形状 (shape)，查看数据集划分后的维度信息。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 8. 模型训练示例 (随机森林分类器)\n",
       "\n",
       "以下代码演示了如何使用随机森林分类器进行模型训练。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "from sklearn.ensemble import RandomForestClassifier\n",
       "from sklearn.datasets import load_iris\n",
       "from sklearn.model_selection import train_test_split\n",
       "\n",
       "# 加载鸢尾花数据集\n",
       "iris = load_iris()\n",
       "X, y = iris.data, iris.target\n",
       "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
       "\n",
       "# 初始化随机森林分类器\n",
       "model = RandomForestClassifier(n_estimators=100, random_state=42)\n",
       "# 使用训练集数据训练模型\n",
       "model.fit(X_train, y_train)\n",
       "\n",
       "print(\"模型训练完成！\")"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "1.  **导入模型和数据集**: 导入 `RandomForestClassifier` (随机森林分类器) 和 `load_iris`, `train_test_split` 等工具。\n",
       "2.  **加载和划分数据**: 加载鸢尾花数据集，并划分训练集和测试集。\n",
       "3.  **初始化模型**: `model = RandomForestClassifier(n_estimators=100, random_state=42)` 创建一个随机森林分类器对象。`n_estimators=100` 设置随机森林中决策树的数量为 100。`random_state=42` 设置随机种子，保证结果可重复。\n",
       "4.  **模型训练**: `model.fit(X_train, y_train)` 使用训练集数据 (`X_train`, `y_train`) 训练模型。`fit()` 方法使模型学习训练数据中的特征和标签之间的关系，调整模型内部参数。\n",
       "5.  **打印训练完成信息**: 打印 \"模型训练完成！\" 提示信息，表示模型训练过程结束。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 9. 模型评估示例 (分类报告和混淆矩阵)\n",
       "\n",
       "以下代码演示了如何使用分类报告和混淆矩阵评估分类模型的性能。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "from sklearn.ensemble import RandomForestClassifier\n",
       "from sklearn.datasets import load_iris\n",
       "from sklearn.model_selection import train_test_split\n",
       "from sklearn.metrics import classification_report, confusion_matrix\n",
       "\n",
       "# 加载鸢尾花数据集并划分数据集 (代码省略，与模型训练示例相同)\n",
       "iris = load_iris()\n",
       "X, y = iris.data, iris.target\n",
       "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
       "model = RandomForestClassifier(n_estimators=100, random_state=42)\n",
       "model.fit(X_train, y_train)\n",
       "\n",
       "# 使用测试集进行预测\n",
       "y_pred = model.predict(X_test)\n",
       "\n",
       "# 打印分类报告，包含精确率、召回率、F1 值、支持度等指标\n",
       "print(\"分类报告:\\n\", classification_report(y_test, y_pred))\n",
       "\n",
       "# 打印混淆矩阵，展示模型在每个类别上的预测情况\n",
       "print(\"\\n混淆矩阵:\\n\", confusion_matrix(y_test, y_pred))"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "1.  **导入评估指标**: 导入 `classification_report` (分类报告) 和 `confusion_matrix` (混淆矩阵) 函数。\n",
       "2.  **加载数据、训练模型**:  (代码省略) 与模型训练示例相同，加载鸢尾花数据集，划分数据集，并训练随机森林分类器模型。\n",
       "3.  **模型预测**: `y_pred = model.predict(X_test)` 使用训练好的模型对测试集数据 `X_test` 进行预测，得到预测的类别标签 `y_pred`。\n",
       "4.  **打印分类报告**: `print(\"分类报告:\\n\", classification_report(y_test, y_pred))` 使用 `classification_report` 函数生成分类报告，并打印输出。分类报告包含精确率 (precision)、召回率 (recall)、F1 值 (f1-score)、支持度 (support) 等指标，用于详细评估模型在每个类别上的性能。\n",
       "5.  **打印混淆矩阵**: `print(\"\\n混淆矩阵:\\n\", confusion_matrix(y_test, y_pred))` 使用 `confusion_matrix` 函数生成混淆矩阵，并打印输出。混淆矩阵以表格形式展示模型在每个类别上的预测情况，包括真正例 (TP)、假正例 (FP)、真反例 (TN)、假反例 (FN) 的数量。"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "### 10. 模型优化示例 (GridSearchCV 超参数调优)\n",
       "\n",
       "以下代码演示了如何使用 GridSearchCV 进行随机森林分类器的超参数调优，寻找最佳的超参数组合。"
      ]
     },
     {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
       "from sklearn.ensemble import RandomForestClassifier\n",
       "from sklearn.datasets import load_iris\n",
       "from sklearn.model_selection import train_test_split, GridSearchCV\n",
       "\n",
       "# 加载鸢尾花数据集并划分数据集 (代码省略)\n",
       "iris = load_iris()\n",
       "X, y = iris.data, iris.target\n",
       "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
       "\n",
       "# 初始化随机森林分类器\n",
       "model = RandomForestClassifier(random_state=42)\n",
       "\n",
       "# 定义超参数网格，要搜索的超参数及其取值范围\n",
       "param_grid = {\n",
       "    'n_estimators': [50, 100, 150, 200], # 决策树数量\n",
       "    'max_depth': [5, 10, 15, None],      # 决策树最大深度\n",
       "    'min_samples_split': [2, 5, 10]      # 节点分裂所需的最小样本数\n",
       "}\n",
       "\n",
       "# 初始化 GridSearchCV，cv=3 表示 3 折交叉验证\n",
       "grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=3, scoring='accuracy', n_jobs=-1)\n",
       "# 使用训练集进行网格搜索和模型训练\n",
       "grid_search.fit(X_train, y_train)\n",
       "\n",
       "# 获取最佳模型\n",
       "best_model = grid_search.best_estimator_\n",
       "# 获取最佳超参数组合\n",
       "best_params = grid_search.best_params_\n",
       "# 获取最佳交叉验证分数\n",
       "best_score = grid_search.best_score_\n",
       "\n",
       "print(\"最佳模型:\\n\", best_model)\n",
       "print(\"\\n最佳超参数:\", best_params)\n",
       "print(\"\\n最佳交叉验证准确率:\", best_score)\n",
       "\n",
       "# 使用最佳模型在测试集上评估性能\n",
       "test_accuracy = best_model.score(X_test, y_test)\n",
       "print(\"\\n最佳模型在测试集上的准确率:\", test_accuracy)"
      ]
     },
     {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
       "**代码解释**：\n",
       "\n",
       "1.  **导入 GridSearchCV**: `from sklearn.model_selection import GridSearchCV` 导入 GridSearchCV 类，用于网格搜索超参数调优。\n",
       "2.  **加载数据、初始化模型**: (代码省略) 加载鸢尾花数据集，划分数据集，并初始化一个随机森林分类器模型。\n",
       "3.  **定义超参数网格**: `param_grid = {...}` 定义一个字典 `param_grid`，包含要搜索的超参数及其取值范围。例如，`'n_estimators': [50, 100, 150, 200]` 表示 `n_estimators` 超参数将在 [50, 100, 150, 200] 这些值中进行搜索。\n",
       "4.  **初始化 GridSearchCV**: `grid_search = GridSearchCV(...)` 创建一个 GridSearchCV 对象。\n",
       "    *   `estimator=model` 设置要优化的模型为 `model` (随机森林分类器)。\n",
       "    *   `param_grid=param_grid` 设置超参数搜索网格为 `param_grid`。\n",
       "    *   `cv=3` 设置交叉验证折数为 3 折。\n",
       "    *   `scoring='accuracy'` 设置评估指标为准确率。\n",
       "    *   `n_jobs=-1` 使用所有 CPU 核心并行计算，加快搜索速度。\n",
       "5.  **网格搜索和模型训练**: `grid_search.fit(X_train, y_train)` 使用训练集数据进行网格搜索和模型训练。`fit()` 方法会自动遍历 `param_grid` 中所有超参数组合，使用交叉验证评估每组超参数的性能，并找到最佳超参数组合。\n",
       "6.  **获取最佳结果**: \n",
       "    *   `best_model = grid_search.best_estimator_` 获取 GridSearchCV 找到的最佳模型 (使用最佳超参数组合训练的模型)。\n",
       "    *   `best_params = grid_search.best_params_` 获取最佳超参数组合。\n",
       "    *   `best_score = grid_search.best_score_` 获取最佳交叉验证分数 (使用最佳超参数组合在交叉验证中获得的平均准确率)。\n",
       "7.  **打印最佳结果**: 打印最佳模型、最佳超参数、最佳交叉验证准确率。\n",
       "8.  **测试集评估**: `test_accuracy = best_model.score(X_test, y_test)` 使用最佳模型在测试集上评估性能，计算测试集准确率。\n",
       "9.  **打印测试集准确率**: 打印最佳模型在测试集上的准确率，评估模型泛化能力。"
      ]
     }
    ],
    "metadata": {
     "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
     },
     "language_info": {
      "codemirror_mode": {
       "name": "ipython",
       "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.5"
     }
    },
    "nbformat": 4,
    "nbformat_minor": 4
   }